<!DOCTYPE html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Visualizations - Single-Source Shortest Paths</title>

<!--css-->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/common.css">
<link rel="stylesheet" href="css/viz.css">

<link rel="stylesheet" href="css/sssp.css"> <!--not yet implemented-->

<!--js-->
<script src="js/external/jquery-1.10.2.js"></script>
<script src="js/external/jquery-ui.js"></script>
<script src="js/external/d3.v3.js"></script>
<script src="js/viz.js"></script>
<script src="js/common.js"></script>
<script src="js/actions/sssp_actions.js"></script> <!--not yet implemented-->
<!--script src="//connect.facebook.net/en_US/all.js"></script-->  <!--I turn off this as this is very slow-->

<!--fonts-->
<link href="fonts/silkscreen/stylesheet.css" rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=PT+Sans:400,700' rel='stylesheet' type='text/css'>

</head>

<body>

<div id="top-bar">
  <a id="home" href="index.html">we<span class="colour">need</span>a<span class="colour">name</span></a>
    <span id="title">
      <a class="selected-viz">Single-Source Shortest Paths</a>
    </span>
    <a id="fb-login" href="#" target="_blank">Facebook connect</a>
    <span id="trick">
    <fb:login-button show-faces="false" width="200" max-rows="1" style="float: right; margin-top: 9px;"></fb:login-button>
    </span>
    <div id="mode-menu">
      <div id="mode-button">Exploration Mode<img src="img/arrow_white.png" alt="Home"/></div>
        <div id="other-modes">
            <a href="#">Tutorial Mode</a>
        </div>
    </div>
</div>
    
    <div id="viz"></div>
    
    <div id="current-action" class="panel"><p></p></div>
    
    <div id="actions" class="panel">
        <p id="sample" class="execAction">Sample Graphs</p>
        <p id="bfs" class="execAction">BFS</p>
        <p id="bellmanford" class="execAction">Bellman Ford's Algo</p>
        <p id="dijkstra" class="execAction">Dijkstra's Algo</p>
    </div>
    <div id="actions-hide" class="panel-hide"><img src="img/arrow_white_right.png" title="show/hide actions panel"/></div>
    <div id="actions-extras">
    <!--put all the extra action pullouts (input) and error messages here-->
      	<div id="samples-err" class="err" style="z-index: 2000;"></div>
        <div id="samples-submenu">
            <div id="sample1" class="execAction" onclick=sample(SSSP_EXAMPLE_CP3_4_3)><p>CP3 4.3 (unweighted)</p></div><!--
            --><div id="sample2" class="execAction" onclick=sample(SSSP_EXAMPLE_CP3_4_17)><p>CP3 4.17</p></div><!--
            --><div id="sample3" class="execAction" onclick=sample(SSSP_EXAMPLE_CP3_4_18)><p>CP3 4.18 (negative weight)</p></div><!--
            --><div id="sample4" class="execAction" onclick=sample(SSSP_EXAMPLE_CP3_4_19)><p>CP3 4.19 (negative cycle)</p></div>
        </div>        
        <div id="bfs-input"><input type="text" id="bfs-v" title="Enter the starting vertex" autocomplete="off" value=0 /></div>
        <div id="bfs-go" class="execAction" onclick=bfs()><p>GO</p></div>
        <div id="bfs-err" class="err"></div>
        <div id="bellmanford-input"><input type="text" id="bellmanford-v" title="Enter the starting vertex" autocomplete="off" value=0 /></div>
        <div id="bellmanford-go" class="execAction" onclick=bellmanford()><p>GO</p></div>
        <div id="bellmanford-err" class="err"></div>
        <div id="dijkstra-input"><input type="text" id="dijkstra-v" title="Enter the starting vertex" autocomplete="off" value=0 /></div>
        <div id="dijkstra-go1" class="execAction" onclick=dijkstra(1) title="Use the original Dijkstra algorithm"><p>Original</p></div>
        <div id="dijkstra-go2" class="execAction" onclick=dijkstra(2) title="Use the modified Dijkstra algorithm"><p>Modified</p></div>
        <div id="dijkstra-err" class="err"></div>
    </div>
    
    <div id="status" class="panel"><p></p></div>
    <div id="status-hide" class="panel-hide"><img src="img/arrow_white_right.png" title="show/hide status panel"/></div>
    
    <div id="codetrace" class="panel">
    <!--can add class "highlighed" to hightlight one line-->
    <p id="code1" style="padding-top: 10px;"></p>
    <p id="code2"></p>
    <p id="code3"></p>
    <p id="code4"></p>
    <p id="code5"></p>
    <p id="code6"></p>
    <p id="code7" style="padding-bottom: 10px;"></p>
    </div>
    <div id="codetrace-hide" class="panel-hide"><img src="img/arrow_white_right.png" title="show/hide codetrace panel"/></div>
    
<div id="left-bar"></div>
<div id="right-bar"></div>
<!-- Bottom bar and overlay popups -->
<div id="bottom-bar">
	<a id="trigger-about">About</a>
    <a id="trigger-team">Team</a>
    <a id="trigger-terms">Terms of use</a>
</div>

<div id="media-controls">
	<div id="speed-control">slow<div id="speed-input"></div>fast</div>
	<span id="go-to-beginning" class="media-control-button" title="go to beginning" onclick=goToBeginning()><img src="img/goToBeginning.png" alt="go to beginning" /></span>
	<span id="previous" class="media-control-button" title="step backward" onclick=stepBackward()><img src="img/prevFrame.png" alt="previous frame" /></span>
    <span id="pause" class="media-control-button" title="pause" onclick=pause()><img src="img/pause.png" alt="pause" /></span>
    <span id="play" class="media-control-button" title="play" onclick=play()><img src="img/play.png" alt="play" /></span>
    <span id="next" class="media-control-button" title="step forward" onclick=stepForward()><img src="img/nextFrame.png" alt="next frame" /></span>
    <span id="go-to-end" class="media-control-button" title="go to end" onclick=goToEnd()><img src="img/goToEnd.png" alt="go to end"/></span>
    <div id="progress-bar" class="media-control-button"></div>
</div>

<div id="dark-overlay"></div>
<div id="about" class="overlays"></div>
<div id="team" class="overlays"></div>
<div id="termsofuse" class="overlays"></div>

<!--tutorial dialogs here-->
<div id="sssp-tutorial-1" class="tutorial-dialog">
	In the Single-Source Shortest Path (SSSP) problem, we aim to find the shortest paths from a particular start node to all other vertices in the graph (if they exist). <br/><br/>Different algorithms can be used depending on the nature of the graph, i.e. weighted/ unweighted, with/without negative weights/ cycles.
     <div class="tutorial-next">Next<img src="img/arrow_white_right.png"/></div>
</div>
<div id="sssp-tutorial-2" class="tutorial-dialog">
	Choose a sample graph <!--or draw your own graph-->and try running the different SSSP algorithms on it:<br/><br/>The O(V + E) <strong>Breadth-first search</strong> (only for unweighted graphs),<br/>The general purpose O(VE) <strong>Bellman Ford's algorithm</strong>, or<br/>The O((V + E) log V) <strong>Dijkstra's algorithm</strong> (only for graphs without negative weights/negative weight cycles)
    <div class="tutorial-next">Next<img src="img/arrow_white_right.png"/></div>
</div>
<div id="sssp-tutorial-3" class="tutorial-dialog">
	When the SSSP algorithm animation is running, the input graph will be shown on the left, and the SSSP spanning tree will be shown on the right with the corresponding distance information.
    <div class="tutorial-next">Next<img src="img/arrow_white_right.png"/></div>
</div>
<div id="sssp-tutorial-4" class="tutorial-dialog">
	The status bar explains the execution of the algorithm at each animation step.
    <div class="tutorial-next">Next<img src="img/arrow_white_right.png"/></div>
</div>
<div id="sssp-tutorial-5" class="tutorial-dialog">
	You can also follow the psuedocode highlights to trace the algorithm.
    <div class="tutorial-next">Next<img src="img/arrow_white_right.png"/></div>
</div>
<div id="sssp-tutorial-6" class="tutorial-dialog">
  Control the animation with the player controls! Keyboard shortcuts are:<br/>
    <div style="margin-top: 8px;"><strong>Spacebar:</strong> play/pause/replay</div>
    <strong>Left/right arrows:</strong> step backward/step forward<br/>
    <strong>-/+:</strong> decrease/increase speed<br/>
    <div class="tutorial-next">Next<img src="img/arrow_white_right.png"/></div>
</div>
<div id="sssp-tutorial-7" class="tutorial-dialog">
  Return to "Exploration Mode" to start exploring!
</div>

<script src="js/graph_library/constant.js"></script>
<script src="js/graph_library/properties.js"></script>
<script src="js/graph_library/helperObjects.js"></script>
<script src="js/graph_library/misc.js"></script>
<script src="js/graph_library/Widget.js"></script>
<script src="js/graph_library/GraphWidget.js"></script>
<script src="js/graph_library/GraphVertexWidget.js"></script>
<script src="js/graph_library/GraphEdgeWidget.js"></script>
<script src="js/widgets/SSSPWidget.js"></script>

<script type="text/javascript">
  //start by showing actions panel
  $('#play').hide();

  var ssspWidget = new SSSP();
  var gw = ssspWidget.getGraphWidget();
  ssspWidget.examples(SSSP_EXAMPLE_CP3_4_17);

  function sample(id) {
    if(isPlaying) { stop(); }
    setTimeout( function() {
      if ((mode=="exploration")&&ssspWidget.examples(id)) {
        $('#progress-bar').slider( "option", "max", 0);
		closeSamples();
        isPlaying = false;
      }
    }, 500);
  }

  function bfs() {
    if(isPlaying) { stop(); }
    var sourceS = parseInt($('#bfs-v').val());
    setTimeout( function() {
      if ((mode=="exploration")&&ssspWidget.bfs(sourceS)) {
        closeBFS();
        $('#current-action').show();
        $('#current-action p').html("BFS(" + sourceS + ")");
        $('#progress-bar').slider( "option", "max", gw.getTotalIteration()-1);
        triggerRightPanels();
        isPlaying = true;
      }
    }, 500);
  }

  function bellmanford() {
    if(isPlaying) { stop(); }
    var sourceS = parseInt($('#bellmanford-v').val());
    setTimeout( function() {
      if ((mode=="exploration")&&ssspWidget.bellmanford(sourceS)) {
        closeBellmanFords();
        $('#current-action').show();
        $('#current-action p').html("BellmanFord(" + sourceS + ")");
        $('#progress-bar').slider( "option", "max", gw.getTotalIteration()-1);
        triggerRightPanels();
        isPlaying = true;
      }
    }, 500);
  }
  
  function dijkstra(versiontype) {
    if(isPlaying) { stop(); }
  	var sourceS = parseInt($('#dijkstra-v').val());
    setTimeout( function() {
      if ((mode=="exploration")&&ssspWidget.dijkstra(sourceS,versiontype)) {
        closeDijkstras();
        $('#current-action').show();
        $('#current-action p').html("Dijkstra(" + sourceS + ")");
        $('#progress-bar').slider( "option", "max", gw.getTotalIteration()-1);
        triggerRightPanels();
        isPlaying = true;
      }
    }, 500);
  }

  //playback controls might fit better in viz.js, but put here in case some viz does not use GraphWidget.js
  var isPaused = false;
  function isAtEnd() {
    return (gw.getCurrentIteration()==(gw.getTotalIteration()-1));
  }
  
  function pause() {
    if(isPlaying) {
      isPaused = true;
      gw.pause();
      $('#play').show();
      $('#pause').hide();
    }
  }
  function play() {
    if(isPlaying) {
      isPaused = false;
      $('#pause').show();
      $('#play').hide();
      if(isAtEnd()) {
        gw.replay();
      } else {
        gw.play();
      }
    }
  }
  function stepForward() {
    if(isPlaying) {
      pause();
      gw.forceNext(250);
    }
  }
  function stepBackward() {
    if(isPlaying) {
      pause();
      gw.forcePrevious(250);  
    }
  }
  function goToBeginning() {
    if(isPlaying) {
      gw.jumpToIteration(0,0);
      pause();
    }
  }
  function goToEnd() {
    if(isPlaying) {
      gw.jumpToIteration(gw.getTotalIteration()-1,0);
      pause();
    }
  }
  function stop() {
    gw.stop();
    isPaused = false;
    isPlaying = false;
    $('#pause').show();
    $('#play').hide();
  }
  
  //shortcut keys for playback controls
  $(document).keydown( function(event) {
    if(event.which == 32) { //spacebar
      if(isPaused) { play(); } else { pause(); }
    } else if(event.which == 37) { //left arrow
      stepBackward();
    } else if(event.which == 39) { //right arrow
      stepForward();
    } else if(event.which == 35) { //end
      stop();
    } else if (event.which == 189) { //minus
      var d = (2200-gw.getAnimationDuration())-100;
      if(d > 0) {
        $("#speed-input").slider("value", d);
      } else {
        $("#speed-input").slider("value", 0);
      }
    } else if (event.which == 187) { //plus
      var d = (2200-gw.getAnimationDuration())+100;
      if(d <= 2000) {
        $("#speed-input").slider("value", d);
      } else {
        $("#speed-input").slider("value", 2000);
      }
    }
  });
  
  //sliders
  $("#speed-input").slider({
    min: 200,
    max: 2000,
    value: 1700,
    change: function(event, ui) {
      gw.setAnimationDuration(2200-ui.value);
    }
  });
  $("#progress-bar").slider({
    range: "min",
    min: 0,
    value: 0,
    slide: function(event, ui) {
      gw.pause();
      gw.jumpToIteration(ui.value,0);
    },
    stop: function(event, ui) {
      if(!isPaused) { setTimeout( function(){gw.play();}, 500) }
    }
  });
  
</script>

</body>
</html>
